package com.iwechat.adapter.mina.entity;

import java.nio.charset.Charset;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.proxy.utils.ByteUtilities;

import com.iwechat.security.coder.MDCoder;
import com.iwechat.util.DataUtil;

/**
 * 下行消息对象
 *
 *
 */
public class Submit extends PDUHeader {
    private static final int command = PDU.COMMAND_SUBMIT;
    /** 业务报文体 */
    private byte[]           body;
    /** 业务报文体摘要 ,16bytes */
    private byte[]           md5;

    /**
     * 根据header构造Submit for receive
     *
     *
     * @param Connect
     * @throws Exception
     */
    public Submit(PDUHeader header, IoBuffer buffer) throws Exception {
        this.pkgLen = header.getPkgLen();
        this.sequence = header.getSequence();
        this.timestamp = header.getTimestamp();
        int bodyLen = pkgLen - 20 - 16;
        body = new byte[bodyLen];
        buffer.get(body);
        md5 = new byte[16];
        buffer.get(md5);
    }

    /**
     * 构造Submit for send
     *
     *
     * @param body
     * @param decoder
     * @throws Exception
     */
    public Submit(String body, Charset charset) throws Exception {
        this.sequence = PDUHeader.getSeqNum();
        this.timestamp = System.currentTimeMillis();
        this.body = body.getBytes(charset);
        this.md5 = new byte[16];
        this.pkgLen = PDU.HEAD_LEN + this.body.length + this.md5.length;
        this.md5 = MDCoder.encodeMD5(this.body);
    }

    /**
     * 获取对象的iobuffer,需要先调用 setters
     *
     * @see com.iwechat.adapter.mina.entity.PDUHeader#toIoBuffer(java.nio.charset.CharsetEncoder)
     */
    @Override
    public IoBuffer toIoBuffer(Charset charset) throws Exception {
        IoBuffer buffer = IoBuffer.allocate(this.pkgLen);
        buffer.putInt(pkgLen);
        buffer.putInt(command);
        buffer.putInt(sequence);
        buffer.putLong(timestamp);

        buffer.put(body);
        buffer.put(MDCoder.encodeMD5(body));
        buffer.flip();
        return buffer;
    }

    /**
     * 检查消息体MD5
     *
     *
     * @return
     * @throws Exception
     */
    public boolean verify() throws Exception {
        boolean ok = false;
        byte[] mymd5 = MDCoder.encodeMD5(body);
        ok = DataUtil.isBytesEquals(mymd5, md5);
        return ok;
    }

    public byte[] getBody() {
        return body;
    }

    public byte[] getMd5() {
        return md5;
    }

    @Override
    public String toString() {
        return "Submit [pkgLen=" + pkgLen + ", command=" + command + ", sequence=" + sequence + ", timestamp=" + timestamp + ", md5="
                + ByteUtilities.asHex(md5) + ", body=" + ByteUtilities.asHex(body) + "]";
    }
}
